package com.iaz.tech.tools.tasks.pool;

import com.iaz.tech.tools.property.IPropertyAble;
import com.iaz.tech.tools.tasks.TaskContext;
import com.iaz.tech.tools.tasks.ability.IScheduleAble;

/**
 * @copyright       :   自由开发
 * @author          :   赵黎民
 * @version         ：  2020.9.27
 * 
 * 用于任务进行调度， 并保证性能
 * 1）调用Thread
 * 2）调度
 * 3）增加任务监控，用于
 */
import com.iaz.tech.tools.tasks.ability.ITaskPoolExecutorAble;
import com.iaz.tech.tools.tasks.impl.BaseTaskItem;

import lombok.Data;
import lombok.EqualsAndHashCode;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@EqualsAndHashCode(callSuper=false)
@Data
public class TaskPoolInvoker extends BaseTaskItem {
    
    /** 
     * 日志
     */
	private final static Logger logger = (Logger) LoggerFactory.getLogger( TaskPoolInvoker.class );
	/**
	 * 构造
	 * @param father
	 */
    public TaskPoolInvoker(ZTecThreadsPool father){
        try{
            if( father == null ){
                throw new Exception("实例化MDTTaskPoolInvoker 异常， 入口参数father 没有指定。");
            }
            this.setItemCode( BaseTaskItem.GenerateItemCode());

        }catch(Exception e){
            logger.error("执行 ZXZTaskPoolInvoker(ZXZThreadsPool father)异常：" + e.getMessage() );  
        }
    }

    @Override
	public void execute(Object sender) { 
        /* 获得线程池，执行调度任务， 该任务现在加载Fix */ 
        ZTecThreadsPool pool = (ZTecThreadsPool)this.getFatherItem();
        try {
            if(pool == null ){
                throw new Exception("任务池没有指定， 无法进行处理。");
            } 
            /* 调度 */
            while( this.isRunning()){
                try {
                    boolean no_free_task = true; 
                    while( pool.hasFreeTask() ) {
                        ITaskPoolExecutorAble task = pool.GetFreeTask();
                        if( task == null ) {                         
                            break;
                        }
                        no_free_task = false;
                        /* 出队 */
                        IScheduleAble schedule = pool.popup();
                        if( schedule != null ) {
                            /* 判断是否满足计划执行的需求 */
                            if(schedule.confirm()) {
                                /* 执行子计划 */
                                task.registerTask(schedule);
                            } else {
                                /* 重新入队 */
                                pool.push(schedule);
                            }                            
                        }else {
                           continue;
                        }                    
                        Thread.sleep(10); 
                    }

                    /* 判断线程池，是否紧张 */
                    if( no_free_task && (pool.getTaskBufferSize() > 0)) {
                        int m_size = pool.getPools_for_normal_once().size();
                        while(m_size < pool.getMaxPoolsSize()) {
                            ExecuteTaskForPool task = new ExecuteTaskForPool();
                            task.setTaskName( ExecuteTaskForPool.generateCode());
                            task.start();
                             /* 出队 */
                            IScheduleAble schedule = pool.popup();
                            if( schedule != null ) {
                                /* 判断是否满足计划执行的需求 */
                                if(schedule.confirm()) {
                                    /* 执行子计划 */
                                    task.registerTask(schedule);
                                } else {
                                    /* 重新入队 */
                                    pool.push(schedule);
                                }
                            }
                            pool.getPools_for_normal_once().add( task);
                            m_size = pool.getPools_for_normal_once().size();
                        }

                    } else {
                        pool.release();
                    }    
                    /* 线程池紧张， 等待一段时间 */
                    Thread.sleep(50);
                }catch(Exception e) {
                    e.printStackTrace();
                    logger.error("执行 execute(Object sender)异常：" + e.getMessage() ); 	                
                }finally {
                    try {
                        Thread.sleep(200);                    
                        if( pool != null ) {
                            pool.release();
                        }                    
                    }catch(Exception exs) {
                        logger.error("执行 Thread.sleep(300);  异常：" + exs.getMessage() ); 	 
                    } 
                }
            }		
        }catch(Exception e) {
            logger.error("执行 execute(Object sender)异常：" + e.getMessage() ); 	                
        }
	}

    /**
     * 停止任务池执行器
     */
    @Override
    public void stop() {
        this.setRunning(false);
    }
}
